<template>
  <div class="component-config">
    <el-form v-if="this.data && Object.keys(this.data).length > 0" label-width="88px" label-position="left" size="mini">
      <el-form-item label="ID">
        <el-input readonly="readonly" v-model="data.prop"></el-input>
      </el-form-item>
      <el-form-item :label="text1" v-if="hasTableSetting">
        <el-select v-model="data.table" placeholder="请选择" @change="handleTableChange">
          <el-option v-for="item in dbTables" :key="item.name" :label="item.name" :value="item.id"> </el-option>
        </el-select>
      </el-form-item>
      <el-form-item :label="text2" v-if="!['gridtable', 'divider', 'viewtable', 'card', 'btn'].includes(data.type)">
        <l-select :options="getFields(data.table)" v-model="data.field" @change="handleFiledChange"> </l-select>
      </el-form-item>
      <el-form-item :label="data.type == 'btn' ? '按钮名称' : '标题名'" v-if="!['divider'].includes(data.type)">
        <el-input v-model="data.label" placeholder="请输入标题名"></el-input>
      </el-form-item>
      <el-form-item
        :label="data.subfield ? '单元格宽度' : '标题宽度'"
        v-if="!['gridtable', 'divider', 'viewtable', 'card', 'btn'].includes(data.type)"
      >
        <el-input-number
          v-model="data.labelWidth"
          controls-position="right"
          placeholder="请输入标题宽度"
          :min="0"
        ></el-input-number>
      </el-form-item>
      <el-form-item
        label="占位提示"
        v-if="
          ![
            'btn',
            'card',
            'gridtable',
            'divider',
            'texteditor',
            'radio',
            'timerange',
            'datetimerange',
            'upload',
            'uploadimg',
            'guid',
            'rate',
            'company',
            'department',
            'modifytime',
            'modifyuser',
            'createtime',
            'createuser',
            'viewtable',
          ].includes(data.type)
        "
      >
        <el-input v-model="data.placeholder" placeholder="请输入占位提示"></el-input>
      </el-form-item>
      <el-form-item label="开始占位" v-if="['timerange', 'datetimerange'].includes(data.type)">
        <el-input v-model="data.startPlaceholder" placeholder="请输入开始占位"></el-input>
      </el-form-item>
      <el-form-item label="结束占位" v-if="['timerange', 'datetimerange'].includes(data.type)">
        <el-input v-model="data.endPlaceholder" placeholder="请输入结束占位"></el-input>
      </el-form-item>
      <el-form-item
        label="表单栅格"
        v-if="!data.subfield && !['gridtable', 'texteditor', 'viewtable'].includes(data.type)"
      >
        <el-slider v-model="data.span" :step="6" :min="6" :max="24" show-stops> </el-slider>
      </el-form-item>

      <component :is="getComponent" :data="data"></component>

      <template v-if="!data.subfield && !isNoScript">
        <el-divider
          v-if="
            [
              'btn',
              'radio',
              'checkbox',
              'select',
              'selectMultiple',
              'treeselect',
              'layerselect',
              'areaselect',
              'companySelect',
              'departmentSelect',
              'userSelect',
              'switch',
            ].includes(data.type)
          "
          >脚本</el-divider
        >
        <div
          class="mt-8"
          v-if="
            [
              'radio',
              'checkbox',
              'select',
              'selectMultiple',
              'treeselect',
              'layerselect',
              'areaselect',
              'companySelect',
              'departmentSelect',
              'userSelect',
              'switch',
            ].includes(data.type)
          "
        >
          <el-button @click="handleBtnClick('changeCode', '值改变脚本')" type="primary" size="mini"
            >值改变脚本</el-button
          >
        </div>
        <div class="mt-8" v-else-if="['btn'].includes(data.type)">
          <el-button @click="handleBtnClick('clickCode', '按钮点击脚本')" type="primary" size="mini"
            >点击脚本</el-button
          >
        </div>
      </template>
    </el-form>
    <div v-else style="width: 100%; text-align: center; margin-top: 100%; color: #909399">请选中组件进行设置！</div>

    <l-dialog
      :title="$t(formTitle)"
      :visible.sync="formVisible"
      :height="528"
      :width="1000"
      @ok="handleCodeSave"
      @opened="handleOpenedForm"
    >
      <l-layout :right="320">
        <l-code-mirror v-model="code" isHint :handleHint="handleHint" mode="application/javascript"></l-code-mirror>
        <template #right>
          <div class="l-rblock" style="padding: 8px; overflow: auto">
            <el-alert title="脚本参数说明,只支持ES5语法（兼容小程序）" type="warning" :closable="false">
              prop:组件id;
              <br />data:组件改变数据; <br />isUpdate:表单状态,新增或更新; <br />get(path):获取数据方法,
              如果想获取某一个组件值就设置path参数值为组件id, 如果是子表的一行数据值就设置子表id.行号,
              如果是子表某一行某一列值就设置子表id.行号.子组件id;
              <br />set(path,value):设置值方法,path说明和get方法一致;
              <br />getLabel(prop):获取组件的显示值,prop为组件id;
              <br />setRequired(prop,isRequired):设置组件是否必填,prop为组件id,isRequired
              默认值true,如果取消必填就设置成false
              <br />setDisabled(prop,isDisabled):设置组件是否只读,prop为组件id,isDisabled
              默认值true,如果取消只读就设置成false <br />setHide(prop,isHide):设置组件是否隐藏,isHide
              默认值true,如果取消隐藏就设置成false <br />httpGet(option):get请求方法 <br />httpPost(option):post请求方法
              <br />httpDelete(option):delete请求方法 <br />httpPut(option):put请求方法
              <br />option:上面四个请求方法参数描述:url:请求地址,data:提交数据(get方法不支持),params:url参数,errorTips:请求失败错误提示,callback请求回调方法
              返回结果为请求数据 <br />loading:显示加载状态 <br />hideLoading:隐藏加载状态 <br />message:显示提示消息
              <br />loginUser:当前登录者信息 <br />callback:回调方法,在脚本里使用了http方法后才需要使用,
              <br />(function(data){ console.log("脚本测试",data); })(learun)
            </el-alert>
          </div>
        </template>
      </l-layout>
    </l-dialog>
  </div>
</template>

<script>
const requireComponent = require.context("./", true, /\.vue$/);
const myComponents = {};
requireComponent.keys().map((fileName) => {
  const name = fileName.split("/")[1].split(".")[0];
  if (name != "cascader") {
    myComponents[`config-${name}`] = requireComponent(fileName).default;
  }
});

export default {
  name: "component-config",
  inject: ["formDesign"],
  props: ["data"],
  components: {
    ...myComponents,
  },
  computed: {
    config() {
      return this.data;
    },
    getComponent() {
      const prefix = "config-";
      const { type } = this.data;
      return prefix + type;
    },
    dbTables() {
      if (this.data.type == "gridtable") {
        return this.formDesign.dbTables.filter((t) => t.type == "chlid");
      } else {
        return this.formDesign.dbTables;
      }
    },
    hasTableSetting() {
      return !this.data.subfield && !["divider", "viewtable", "card", "btn"].includes(this.data.type); //&& this.dbTables.length > 1
    },
    isNoScript() {
      return this.formDesign.isNoScript;
    },
  },
  data() {
    return {
      formVisible: false,
      type: "",
      formTitle: "",
      code: "",
      text1: "数据表",
      text2: "字段名",
    };
  },
  methods: {
    //表单类型
    getFormType(type) {
      if (type == 2) {
        this.text1 = "数据结构";
        this.text2 = "字段名";
      } else {
        this.text1 = "数据表";
        this.text2 = "字段名";
      }
      this.formDesign.formType = type;
      return type;
    },

    handleTableChange(val) {
      if (this.data.type == "gridtable" && this.data.children) {
        this.data.children.forEach((item) => {
          item.table = val;
        });
      }
    },

    getFields(tableName) {
      let table = this.formDesign.dbTables.find((t) => t.name == tableName) || {};
      const columns = table.columns || [];
      return columns.map((t) => ({ ...t, value: t.name, label: t.coment ? `${t.name}(${t.coment})` : t.name }));
    },

    //字段改变事件
    handleFiledChange(obj) {
      var _this = this;
      _this.formDesign.dbTables.forEach(function (v) {
        v.columns.forEach(function (sv) {
          if (sv.name === _this.data.field) _this.data.default = sv.value || "";
        });
      });
      if (obj) {
        this.config.csType = obj.csType;
        if (["switch"].includes(this.config.type)) {
          switch (this.config.csType) {
            case "int":
              this.config.activeValue = "1";
              this.config.inactiveValue = "0";
              this.config.valueType = "number";
              break;
            case "bool":
              this.config.activeValue = "true";
              this.config.inactiveValue = "false";
              this.config.valueType = "boolean";
              break;
            default:
              this.config.valueType = "string";
              break;
          }
        }
      } else {
        this.config.csType = "";
      }
    },

    handleBtnClick(type, title) {
      this.type = type;
      this.formTitle = title;
      this.formVisible = true;
    },
    getEvent(strEvent) {
      // 获取事件方法
      if (!this.$validatenull(strEvent)) {
        if (strEvent.indexOf("=>") != -1) {
          // 表示是老版本，提示其修改为新的版本
          console.warn("当前脚本不支持ES6语法，只支持ES5语法");
          return { res: false, msg: "脚本没有更新为最新的版本！" };
        } else {
          strEvent = `(function(){function fn(learun) {${strEvent}} return fn})()`;
          return this.$getFunction(strEvent);
        }
      } else {
        return { res: true };
      }
    },
    handleCodeSave() {
      const { res, msg } = this.getEvent(this.code);
      if (res) {
        this.data[this.type] = this.code;
        this.formVisible = false;
      } else {
        this.$message({
          type: "error",
          message: `脚本错误:${msg}`,
        });
      }
    },
    handleOpenedForm() {
      this.code = this.data[this.type] || "";
    },
    handleHint(text) {
      text = text.replace(/'/g, "");
      text = text.replace(/"/g, "");
      const list = this.formDesign.nowComponentList.filter(
        (t) => t.label.indexOf(text) != -1 || t.prop.indexOf(text) != -1
      );
      return list.map((t) => `/*${t.label}*/"${t.prop}"`);
    },
  },
};
</script>
